home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / samples.tk / blendeq.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  7KB  |  325 lines

  1. /*
  2.  * ** blendeq.c - Demonstrates the use of the blend_minmax, blend_subtract,
  3.  * **    and blend_logic_op extensions using glBlendEquationEXT.
  4.  * **
  5.  * **    Over a two-color backround, draw rectangles using twelve blend
  6.  * **    options.  The values are read back as UNSIGNED_BYTE and printed
  7.  * **    in hex over each value.  These values are useful for logic
  8.  * **    op comparisons when channels are 8 bits deep.
  9.  */
  10.  
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include "gltk.h"
  16.  
  17. GLenum doubleBuffer, directRender;
  18. static int dithering = 0;
  19. static int doPrint = 1;
  20. static int deltaY;
  21. GLint windW, windH;
  22. GLuint bitmapBase;
  23.  
  24. static void Init(void)
  25. {
  26.   bitmapBase = glGenLists(256);
  27.   if (tkCreateBitmapFont(bitmapBase) == GL_FALSE) {
  28.     tkQuit();
  29.   }
  30.  
  31.   glDisable(GL_DITHER);
  32.   glShadeModel(GL_FLAT);
  33. }
  34.  
  35. static void Reshape(int width, int height)
  36. {
  37.  
  38.   windW = (GLint) width;
  39.   windH = (GLint) height;
  40.  
  41.   glViewport(0, 0, (GLint) width, (GLint) height);
  42.   deltaY = windH / 16;
  43.  
  44.   glMatrixMode(GL_PROJECTION);
  45.   glLoadIdentity();
  46.   gluOrtho2D(0, windW, 0, windH);
  47.   glMatrixMode(GL_MODELVIEW);
  48. }
  49.  
  50. static GLenum Key(int key, GLenum mask)
  51. {
  52.  
  53.   switch (key) {
  54.     case TK_ESCAPE:
  55.       tkQuit();
  56.     case TK_d:
  57.       dithering = !dithering;
  58.       break;
  59.     default:
  60.       return GL_FALSE;
  61.   }
  62.   return GL_TRUE;
  63. }
  64.  
  65. static void PrintColorStrings(void)
  66. {
  67.   GLubyte ubbuf[3];
  68.   int i, xleft, xright;
  69.   char colorString[18];
  70.  
  71.   xleft = 5 + windW / 4;
  72.   xright = 5 + windW / 2;
  73.  
  74.   for (i = windH - deltaY + 4; i > 0; i -= deltaY) {
  75.     glReadPixels(xleft, i + 10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
  76.     sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
  77.         ubbuf[0], ubbuf[1], ubbuf[2]);
  78.     glRasterPos2f(xleft, i);
  79.     tkDrawStr(bitmapBase, colorString);
  80.     glReadPixels(xright, i + 10, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, ubbuf);
  81.     sprintf(colorString, "(0x%x, 0x%x, 0x%x)",
  82.         ubbuf[0], ubbuf[1], ubbuf[2]);
  83.     glRasterPos2f(xright, i);
  84.     tkDrawStr(bitmapBase, colorString);
  85.   }
  86. }
  87.  
  88. static void Draw(void)
  89. {
  90.   int stringOffset = 5, stringx = 8;
  91.   int x1, x2, xleft, xright;
  92.   int i;
  93.  
  94.   (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
  95.   glDisable(GL_BLEND);
  96.  
  97.   glClearColor(0.5, 0.6, 0.1, 1.0);
  98.   glClear(GL_COLOR_BUFFER_BIT);
  99.  
  100.   /*
  101.    * Draw background 
  102.    */
  103.   glColor3f(0.1, 0.1, 1.0);
  104.   glRectf(0.0, 0.0, windW / 2, windH);
  105.  
  106.   /*
  107.    * Draw labels 
  108.    */
  109.   glColor3f(0.8, 0.8, 0.0);
  110.   i = windH - deltaY + stringOffset;
  111.   glRasterPos2f(stringx, i);
  112.   i -= deltaY;
  113.   tkDrawStr(bitmapBase, "SOURCE");
  114.   glRasterPos2f(stringx, i);
  115.   i -= deltaY;
  116.   tkDrawStr(bitmapBase, "DEST");
  117.   glRasterPos2f(stringx, i);
  118.   i -= deltaY;
  119.   tkDrawStr(bitmapBase, "min");
  120.   glRasterPos2f(stringx, i);
  121.   i -= deltaY;
  122.   tkDrawStr(bitmapBase, "max");
  123.   glRasterPos2f(stringx, i);
  124.   i -= deltaY;
  125.   tkDrawStr(bitmapBase, "subtract");
  126.   glRasterPos2f(stringx, i);
  127.   i -= deltaY;
  128.   tkDrawStr(bitmapBase, "reverse_subtract");
  129.   glRasterPos2f(stringx, i);
  130.   i -= deltaY;
  131.   tkDrawStr(bitmapBase, "clear");
  132.   glRasterPos2f(stringx, i);
  133.   i -= deltaY;
  134.   tkDrawStr(bitmapBase, "set");
  135.   glRasterPos2f(stringx, i);
  136.   i -= deltaY;
  137.   tkDrawStr(bitmapBase, "copy");
  138.   glRasterPos2f(stringx, i);
  139.   i -= deltaY;
  140.   tkDrawStr(bitmapBase, "noop");
  141.   glRasterPos2f(stringx, i);
  142.   i -= deltaY;
  143.   tkDrawStr(bitmapBase, "and");
  144.   glRasterPos2f(stringx, i);
  145.   i -= deltaY;
  146.   tkDrawStr(bitmapBase, "invert");
  147.   glRasterPos2f(stringx, i);
  148.   i -= deltaY;
  149.   tkDrawStr(bitmapBase, "or");
  150.   glRasterPos2f(stringx, i);
  151.   i -= deltaY;
  152.   tkDrawStr(bitmapBase, "xor");
  153.  
  154.   i = windH - deltaY;
  155.   x1 = windW / 4;
  156.   x2 = 3 * windW / 4;
  157.   xleft = 5 + windW / 4;
  158.   xright = 5 + windW / 2;
  159.  
  160.   /*
  161.    * Draw foreground color for comparison 
  162.    */
  163.   glColor3f(0.9, 0.2, 0.8);
  164.   glRectf(x1, i, x2, i + deltaY);
  165.  
  166.   /*
  167.    * Leave one rectangle of background color 
  168.    */
  169.  
  170.   /*
  171.    * Begin test cases 
  172.    */
  173.   glEnable(GL_BLEND);
  174.   glBlendFunc(GL_ONE, GL_ONE);
  175.  
  176.   i -= 2 * deltaY;
  177.   glBlendEquationEXT(GL_MIN_EXT);
  178.   glRectf(x1, i, x2, i + deltaY);
  179.  
  180.   i -= deltaY;
  181.   glBlendEquationEXT(GL_MAX_EXT);
  182.   glRectf(x1, i, x2, i + deltaY);
  183.  
  184.   i -= deltaY;
  185.   glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
  186.   glRectf(x1, i, x2, i + deltaY);
  187.  
  188.   i -= deltaY;
  189.   glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
  190.   glRectf(x1, i, x2, i + deltaY);
  191.  
  192.   glBlendFunc(GL_ONE, GL_ZERO);
  193.   i -= deltaY;
  194.   glBlendEquationEXT(GL_LOGIC_OP);
  195.   glLogicOp(GL_CLEAR);
  196.   glRectf(x1, i, x2, i + deltaY);
  197.  
  198.   i -= deltaY;
  199.   glBlendEquationEXT(GL_LOGIC_OP);
  200.   glLogicOp(GL_SET);
  201.   glRectf(x1, i, x2, i + deltaY);
  202.  
  203.   i -= deltaY;
  204.   glBlendEquationEXT(GL_LOGIC_OP);
  205.   glLogicOp(GL_COPY);
  206.   glRectf(x1, i, x2, i + deltaY);
  207.  
  208.   i -= deltaY;
  209.   glBlendEquationEXT(GL_LOGIC_OP);
  210.   glLogicOp(GL_NOOP);
  211.   glRectf(x1, i, x2, i + deltaY);
  212.  
  213.   i -= deltaY;
  214.   glBlendEquationEXT(GL_LOGIC_OP);
  215.   glLogicOp(GL_AND);
  216.   glRectf(x1, i, x2, i + deltaY);
  217.  
  218.   i -= deltaY;
  219.   glBlendEquationEXT(GL_LOGIC_OP);
  220.   glLogicOp(GL_INVERT);
  221.   glRectf(x1, i, x2, i + deltaY);
  222.  
  223.   i -= deltaY;
  224.   glBlendEquationEXT(GL_LOGIC_OP);
  225.   glLogicOp(GL_OR);
  226.   glRectf(x1, i, x2, i + deltaY);
  227.  
  228.   i -= deltaY;
  229.   glBlendEquationEXT(GL_LOGIC_OP);
  230.   glLogicOp(GL_XOR);
  231.   glRectf(x1, i, x2, i + deltaY);
  232.   glRectf(x1, i + 10, x2, i + 5);
  233.  
  234.   if (doPrint) {
  235.     glDisable(GL_BLEND);
  236.     glColor3f(1.0, 1.0, 1.0);
  237.     PrintColorStrings();
  238.   }
  239.   glFlush();
  240.  
  241.   if (doubleBuffer) {
  242.     tkSwapBuffers();
  243.   }
  244.  
  245. }
  246.  
  247. static GLenum Args(int argc, char **argv)
  248. {
  249.   GLint i;
  250.  
  251.   doubleBuffer = GL_FALSE;
  252.   directRender = GL_TRUE;
  253.  
  254.   for (i = 1; i < argc; i++) {
  255.     if (strcmp(argv[i], "-sb") == 0) {
  256.       doubleBuffer = GL_FALSE;
  257.     }
  258.     else if (strcmp(argv[i], "-db") == 0) {
  259.       doubleBuffer = GL_TRUE;
  260.     }
  261.     else if (strcmp(argv[i], "-dr") == 0) {
  262.       directRender = GL_TRUE;
  263.     }
  264.     else if (strcmp(argv[i], "-ir") == 0) {
  265.       directRender = GL_FALSE;
  266.     }
  267.     else {
  268.       printf("%s (Bad option).\n", argv[i]);
  269.       return GL_FALSE;
  270.     }
  271.   }
  272.   return GL_TRUE;
  273. }
  274.  
  275. void main(int argc, char **argv)
  276. {
  277.   GLenum type;
  278.   char *s;
  279.   char *extName1 = "GL_EXT_blend_logic_op";
  280.   char *extName2 = "GL_EXT_blend_minmax";
  281.   char *extName3 = "GL_EXT_blend_subtract";
  282.  
  283.   if (Args(argc, argv) == GL_FALSE) {
  284.     tkQuit();
  285.   }
  286.  
  287.   tkInitPosition(0, 0, 800, 400);
  288.  
  289.   type = TK_RGB;
  290.   type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  291.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  292.   tkInitDisplayMode(type);
  293.  
  294.   if (tkInitWindow("Blend Equation") == GL_FALSE) {
  295.     tkQuit();
  296.   }
  297.  
  298.   /*
  299.    * Make sure blend_logic_op extension is there. 
  300.    */
  301.   s = (char *)glGetString(GL_EXTENSIONS);
  302.   if (!s)
  303.     tkQuit();
  304.   if (strstr(s, extName1) == 0) {
  305.     printf("Blend_logic_op extension is not present.\n");
  306.     tkQuit();
  307.   }
  308.   if (strstr(s, extName2) == 0) {
  309.     printf("Blend_minmax extension is not present.\n");
  310.     tkQuit();
  311.   }
  312.   if (strstr(s, extName3) == 0) {
  313.     printf("Blend_subtract extension is not present.\n");
  314.     tkQuit();
  315.   }
  316.  
  317.   Init();
  318.  
  319.   tkExposeFunc(Reshape);
  320.   tkReshapeFunc(Reshape);
  321.   tkKeyDownFunc(Key);
  322.   tkDisplayFunc(Draw);
  323.   tkExec();
  324. }
  325.